home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
Cheat II
/
original
/
cheat.c
next >
Wrap
Text File
|
1995-09-05
|
14KB
|
544 lines
// cheat.c
// an excuse for a filename
#include <string.h>
#include <pascal.h>
#include "main.h"
#include "cheatWindow.h"
#include "ResRefs.h"
#include "cheat.h"
#include "error.h"
#include "cheatwich.h"
#include "cheatfile.h"
shortcut wichcuts[kmaxwichcuts];
int numwichcuts = 0;
// test if a char is fit to be processed by the TEManager
int numbKey(char c) // a numb key is defined by not having feelings
// (boy am I witty)
{
int res = false, i;
char *valid = " 0123456789.-";
valid[0] = (char) 8; // delete, I think
for (i=0;valid[i];i++)
res |= (c == valid[i]);
return res;
}
// pop up a simple alert with given string as the text, one okay button
void stdmessage(Str255 s)
{
ParamText(s, "\p", "\p", "\p");
(void) Alert(rmessagealrt, nil);
}
// converts the text in the TE field to a longint
long HandToLong(TEHandle h)
{
Str255 str;
long l;
int i;
str[0] = (char) (**h).teLength;
for (i=1;i<=str[0], i<200;i++)
str[i] = ((*((char **) (**h).hText))[i-1]);
StringToNum(str, &l);
return l;
}
// moves the text in the TE into scratch
static void HandToScratch(TEHandle h)
{
int i;
for (i=0;i<256;i++)
scratch[i] = ((*((char **) (**h).hText))[i]);
scratch[i] = 0;
if ((**h).teLength < 256)
scratch[(**h).teLength] = 0;
}
// when the user hits a key, let's do some shit
void HandleKey(char c)
{
float diff;
int i;
if (numbKey(c)) {
}
}
// the user hit the search button, so let's do it
void searchButtonHit(void)
{
Cell cell = {0, 0};
int *pint, findint, temp;
void *p;
long endsearch, findlong, newposs, *plong, l, startsearch;
Str255 str;
Boolean isbolo;
// get the number to search for from the text field
GetIText(ditem[riSearchNum], str);
StringToNum(str, &findlong);
findint = findlong;
if (LGetSelect(true, &cell, plist)) { // must have selected an app
isbolo = *((long *) ((long) InfoRec[cell.v].processName + 1)) == 'Bolo';
if (isbolo)
gcurposs = 0;
else {
p = (void *) ((long) InfoRec[cell.v].processLocation + InfoRec[cell.v].processSize);
startsearch = (long) p;
if (!gcurposs) { // starting a new search
// p is start of search, at the largest location in that app's partition
endsearch = (long) InfoRec[cell.v].processLocation;
pint = (int *) p; plong = (long *) p;
switch (gvalsize) {
case ksizelong:
while ((long) plong >= endsearch) {
plong = (long *) ((long) plong - 2); // only decrement two bytes
if (*plong == findlong) { // we've found a possibility
gposs[gcurposs++] = (Ptr) plong; // store it
if (gcurposs>=gmaxposs) // too many values
plong = (void *) (endsearch-4); // this will kill the search
}
}
break;
case ksizeint:
while ((long) pint >= endsearch)
if (*--pint == findint) { // we've found a possibility
gposs[gcurposs++] = (Ptr) pint; // store it
if (gcurposs>=gmaxposs) // too many values
pint = (void *) (endsearch-4); // this will kill the search
}
break;
case ksizebyte:
while ((long) pint >= endsearch) {
pint--;
// first look at high-order byte
temp = (*pint) >> 8;
if (temp == findint) { // we've found a possibility
gposs[gcurposs++] = (Ptr) pint; // store it
if (gcurposs>=gmaxposs) // too many values
pint = (void *) (endsearch-4); // this will kill the search
}
// now look at low-order byte
temp = (*pint) & 0xFF;
if (temp == findint) { // we've found a possibility
gposs[gcurposs++] = (Ptr) ((long) pint + 1); // store it
if (gcurposs>=gmaxposs) // too many values
pint = (void *) (endsearch-4); // this will kill the search
}
}
break;
default: break;
}
}
else { // refining a search
newposs = 0;
switch (gvalsize) {
case ksizelong: // we're dealing in longints
for (l=0;l<gcurposs;l++)
if (*((long *)gposs[l]) == findlong)
gposs[newposs++] = gposs[l];
break;
case ksizeint: // we're dealing in integers
for (l=0;l<gcurposs;l++)
if (*((int *)gposs[l]) == findint)
gposs[newposs++] = gposs[l];
break;
case ksizebyte: // we're dealing in bytes
for (l=0;l<gcurposs;l++)
if ((long) gposs[l] & 1) { // some are odd
// extract low order byte
if ((*((int *)((long) gposs[l] - 1)) & 0xFF) == findint)
gposs[newposs++] = gposs[l];
}
else if ((*((int *)gposs[l]) >> 8) == findint)
gposs[newposs++] = gposs[l];
break;
default: break;
}
gcurposs = newposs;
}
}
// change the text field of the possibilities item
NumToString(gcurposs, str);
SetIText(ditem[riPossibilities], str);
// change the text field of the offset item
goffset = startsearch - (long) gposs[0];
if (gcurposs)
NumToString(goffset, str);
else
str[0] = 0; // empty string
SetIText(ditem[riOffset], str);
}
DrawFoundPic(); // might have narrowed, etc
fixshortbuttz();
}
// called when user switches apps or hits Start Over button
void doStartOver(void)
{
Str255 str = "\p0";
SetIText(ditem[riPossibilities], str);
// SetIText(ditem[riSearchNum], str);
gcurposs = 0;
// clear the offset text
str[0] = 0;
SetIText(ditem[riOffset], str);
goffset = 0;
DrawFoundPic(); // definitely clouds
fixshortbuttz();
}
// called when user selects the size of what they're searching for
void doSizeChange(short item)
{
Str255 str = "\p0";
setSearchSize(item - riSizeLong);
// we unfortunately must reset some things, but not everything
SetIText(ditem[riPossibilities], str);
gcurposs = 0;
// clear the offset text
str[0] = 0;
SetIText(ditem[riOffset], str);
goffset = 0;
DrawFoundPic(); // definitely clouds
fixshortbuttz();
}
// called when user selects how they want to find the process
void doRuptOrSelect(short item)
{
int delta = item - riSelecting;
Cell cell = {0, 0};
if (ghowfind == delta)
return; // no need
setFindGameBy(delta);
if (delta)
installTMTask();
else
removeTMTask();
if (LGetSelect(true, &cell, plist))
LSetSelect(false, cell, plist);
}
// called when a user hits the change button
void doChange(void)
{
Cell cell = {0, 0};
Str255 str;
long l;
int changeto, *ip, temp;
short res;
if (goffset == 0) {
stdmessage("\pError: offset of 0 cannot be valid");
return;
}
if (LGetSelect(true, &cell, plist)) { // must have selected an app
if (gcurposs>1) { // they have more than one piece of data they want to change
res = Alert(rYouSureAlrt, 0); // ask them
if (res != 1)
return; // their mistake
}
GetIText(ditem[riNewValue], str);
StringToNum(str, &l);
changeto = l;
switch (gvalsize) {
case ksizelong: // we're dealing in longints
*((long *) gposs[0]) = l; // set the place in memory!
break;
case ksizeint: // we're dealing in integers
if (l > 65535) {
stdmessage("\pError: Change To value is too large for integer.");
return;
}
*((int *) gposs[0]) = changeto; // set the place in memory!
break;
case ksizebyte:
if (l > 255) {
stdmessage("\pError: Change To value is too large for byte.");
return;
}
if ((long) gposs[0] & 1) { // odd address
ip = (int *) ((long) gposs[0] - 1); // set at word right before byte
// change the low-order byte of this word to what we want
temp = (((*ip) >> 8) << 8) + (changeto & 0xFF);
*ip = temp; // set it in memory
}
else {
ip = (int *) gposs[0]; // treat as word pointer
// change the high-order byte of this word to what we want
temp = (((*ip) << 8) >> 8) + ((changeto & 0xFF) << 8);
*ip = temp; // set it in memory
}
break;
default: verify(false); break;
}
}
}
// user clicks on Add button in Cheat Sheet
void doAddCheat(void)
{
shortcut newcut;
Str255 s;
long l;
short id;
Cell cell, well = {0, 0};
Handle h;
if (!gcurposs) {
stdmessage("\pSorry, you haven't located a cheat yet.");
return;
}
// if (!LGetSelect(true, &well, plist)) { // find selected app
// stdmessage("\pYou must have a game selected when adding a cheat.");
// return;
// }
// fill fields of the struct w/ appropriate values
// damn, I should be reading Plato right now
GetIText(ditem[riTitle], newcut.title);
if (!newcut.title[0]) {
stdmessage("\pYou must enter a title before adding a cheat.");
return;
}
if (goffset>150000)
stdmessage("\pWarning: value saved is reasonably likely to move about, thus saved position may not work again.");
GetIText(ditem[riComment], newcut.comment);
GetIText(ditem[riNewValue], s);
StringToNum(s, &newcut.newval);
newcut.datasize = gvalsize;
if (LGetSelect(true, &well, plist)) {
l = (long) InfoRec[well.v].processLocation + InfoRec[well.v].processSize;
newcut.offset = l - (long) gposs[0];
}
else
newcut.offset = goffset;
// try to grow our records
SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
if (MemError()) {
stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
return;
}
HLock((Handle) cut);
(*cut)[gnumcuts] = newcut;
HUnlock((Handle) cut);
// add a cell in the list
cell.v = LAddRow(1, -1, slist);
cell.h = 0;
LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
gnumcuts++;
// add the resource to our file
h = NewHandle(sizeof(shortcut));
verify(h);
HLock(h);
**((shortcut **) h) = newcut;
HUnlock(h);
id = Unique1ID(kcheatsheettype);
AddResource(h, kcheatsheettype, id, newcut.title);
if (ResError())
stdmessage("\pI was unable to save this cheat.");
else {
WriteResource(h);
ReleaseResource(h);
}
// DisposHandle(h);
}
// save the shortcuts that were saved into ram during the last cheatwich
void addwichcuts (void)
{
shortcut newcut;
Str255 s;
long l;
short id;
Cell cell, well = {0, 0};
Handle h;
int i;
for (i=0;i<numwichcuts;i++) {
newcut = wichcuts[i];
verify(cut);
SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
if (MemError()) {
stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
return;
}
HLock((Handle) cut);
(*cut)[gnumcuts] = newcut;
HUnlock((Handle) cut);
// add a cell in the list
cell.v = LAddRow(1, -1, slist);
cell.h = 0;
LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
gnumcuts++;
// add the resource to our file
h = NewHandle(sizeof(shortcut));
verify(h);
HLock(h);
**((shortcut **) h) = newcut;
HUnlock(h);
id = Unique1ID(kcheatsheettype);
AddResource(h, kcheatsheettype, id, newcut.title);
if (ResError())
stdmessage("\pI was unable to save this cheat.");
else {
WriteResource(h);
ReleaseResource(h);
}
}
numwichcuts = 0;
}
// called when a user hits the open cheat button or double clicks on a cell
void doOpenCheat(void)
{
Cell cell = {0, 0}, well = {0, 0};
Str255 str;
long l;
short res;
if (!LGetSelect(true, &well, plist)) {
stdmessage("\pYou must have a game selected before opening a cheat.");
return;
}
if (LGetSelect(true, &cell, slist)) { // must have selected a shortcut
HLock((Handle) cut);
// we want to transfer data to the main window, etc.
gcurposs = 1;
NumToString(gcurposs, str);
SetIText(ditem[riPossibilities], str);
gposs[0] = (Ptr) ((long) InfoRec[well.v].processLocation +
InfoRec[well.v].processSize - (*cut)[cell.v].offset);
goffset = (*cut)[cell.v].offset;
NumToString(goffset, str);
SetIText(ditem[riOffset], str);
NumToString((*cut)[cell.v].newval, str);
SetIText(ditem[riNewValue], str);
verify((*cut)[cell.v].datasize >=0 && (*cut)[cell.v].datasize <= 2);
setSearchSize((*cut)[cell.v].datasize);
SetIText(ditem[riTitle], (*cut)[cell.v].title);
SetIText(ditem[riComment], (*cut)[cell.v].comment);
HUnlock((Handle) cut);
DrawFoundPic(); // might change
fixshortbuttz();
}
}
// return the length of the selection (in cells) of the slist
static int selength(void)
{
Cell cell = {0, 0};
int count = 1;
if (!LGetSelect(true, &cell, slist))
return 0;
cell.v++;
while (LGetSelect(false, &cell, slist)) {
count++;
cell.v++;
}
return count;
}
// user clicks on Remove button in Cheat Sheet
void doRemoveCheat(void)
{
shortcut newcut;
Str255 s;
long l;
short i, woop;
Cell cell = {0, 0};
Handle h;
int sels = selength();
if (!LGetSelect(true, &cell, slist)) { // find selected app
stdmessage("\pYou must have a cheat selected.");
return;
}
HLock((Handle) cut);
for (woop=0; woop < sels; woop++) {
LDelRow(1, cell.v, slist); // remove from list
// remove from resource fork
h = Get1NamedResource(kcheatsheettype, (*cut)[cell.v].title);
if (h)
RmveResource(h);
if (ResError())
stdmessage("\pAn error occurred, and I was unable to remove this cheat from the file.");
// slide information down
for (i = cell.v; i + 1 < gnumcuts; i++)
(*cut)[i] = (*cut)[i+1];
}
HUnlock((Handle) cut);
gnumcuts--;
}
void doExportShortcut(int how)
{
Cell cell = {0, 0};
if (!LGetSelect(true, &cell, slist)) {
stdmessage("\pYou must have a game selected before opening a cheat.");
return;
}
if (LGetSelect(true, &cell, slist)) { // must have selected a shortcut
HLock((Handle) cut);
doSaveFile(how, &((*cut)[cell.v]), selength());
HUnlock((Handle) cut);
}
}
extern int wegotfile; // from cheatfile
void fixshortbuttz(void)
{
int sels = selength();
HiliteControl((ControlHandle) sitem[riExportNew], sels ? 0 : 255);
HiliteControl((ControlHandle) sitem[riAppendToOld], (sels&&wegotfile) ? 0 : 255);
HiliteControl((ControlHandle) sitem[riExportAppend], sels ? 0 : 255);
HiliteControl((ControlHandle) sitem[riOpenCheat], (sels == 1) ? 0 : 255);
HiliteControl((ControlHandle) sitem[riRemoveCheat], sels ? 0 : 255);
HiliteControl((ControlHandle) sitem[riAddCheat], goffset ? 0 : 255);
}